package cn.cloudplug.ui.view;

import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.Point;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import java.util.ArrayList;

import cn.cloudplug.core.util.MyUtil;
import cn.cloudplug.core.util.log.LogUtil;
import cn.cloudplug.ui.R;

/**
 * Created by pc on 2018/1/29.
 */

public class TurnStyleMenu extends RelativeLayout {

    private static final int VIEW_COUNT = 9;
    private static final float ALPHA_MIN = 0.5f;
    private static final float SCALE_MIN = 0.72f;
    private static final int MAX_ITEM = 5;
    private static final int ICON_SIZE = 60;
    private int radius;
    private int startAngle=0;
    private int angle;
    private ArrayList<OptionItem> subActionItems = new ArrayList<>();
    private ArrayList<View> mViews = new ArrayList<>();
    private OnMenuItemClickListener onMenuItemClickListener=null;
    private Point center;
    private int currPosition=-1;
    private LayoutInflater inflate = LayoutInflater.from(getContext());
    private boolean isMove = false;
    private float startMove = -1;
    private Integer rightMost = null;
    private Integer rightSecond = null;
    private int checkItem;
    private View.OnClickListener onClickListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            int position=mViews.indexOf(v);
            positionScrollTo(position);
            if(position==getCurrPosition()&&onMenuItemClickListener!=null){
                ViewHolder viewHolder = (ViewHolder) v.getTag();
                if(viewHolder!=null&&viewHolder.item!=null){
                    onMenuItemClickListener.onMenuItemClick(viewHolder.item);
                }
            }
        }
    };
    private View.OnTouchListener onTouchListener = new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            userTouch(event);
            return false;
        }
    };
    private RectF area;

    public TurnStyleMenu(Context context) {
        super(context);
        init();
    }

    public TurnStyleMenu(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public int getCurrPosition() {
        return currPosition;
    }

    public void setCurrPosition(int currPosition) {
        while (currPosition>=VIEW_COUNT){currPosition-=VIEW_COUNT;}
        while (currPosition<0){currPosition=currPosition+VIEW_COUNT;}
        if(this.currPosition!=currPosition){
            int q=(currPosition==0&&this.currPosition==VIEW_COUNT-1)?1:((currPosition==VIEW_COUNT-1&&this.currPosition==0)?-1:(currPosition-this.currPosition));
            setCheckItem(checkItem+q);
            //LogUtil.e("q","currPosition:"+currPosition+" this.currPosition:"+this.currPosition+"q"+q);
            this.currPosition = currPosition;
        }
    }

    private int getOffsetCurrPosition(int i){
        int x=getCurrPosition()+i;
        while (x>=VIEW_COUNT){x-=VIEW_COUNT;}
        while (x<0){x=x+VIEW_COUNT;}
        return x;
    }

    private int getOffsetCurrCheckItem(int i){
        int x=getCheckItem()+i;
        while (x>=MAX_ITEM){x-=MAX_ITEM;}
        while (x<0){x=x+MAX_ITEM;}
        return x;
    }

    public int getCheckItem() {
        return checkItem;
    }

    public void setCheckItem(int checkItem) {
        while (checkItem>=MAX_ITEM){checkItem-=MAX_ITEM;}
        while (checkItem<0){checkItem=checkItem+MAX_ITEM;}
        this.checkItem = checkItem;
    }

    private ViewHolder[] getShowHolders(){
        ViewHolder[] viewHolders = new ViewHolder[7];
        viewHolders[0]=getViewHolder(getCurrPosition());
        viewHolders[1]=getViewHolder(getOffsetCurrPosition(1));
        viewHolders[2]=getViewHolder(getOffsetCurrPosition(2));
        viewHolders[3]=getViewHolder(getOffsetCurrPosition(-2));
        viewHolders[4]=getViewHolder(getOffsetCurrPosition(-1));
        viewHolders[5]=getViewHolder(getOffsetCurrPosition(-3));
        viewHolders[6]=getViewHolder(getOffsetCurrPosition(3));
        return viewHolders;
    }

    public void setStartAngle(int i){
         i=i%360;
         if(i>180)i=i-360;else if(i<180)i=360+i;
         startAngle=i;
        invalidateItem();
    }

    //添加item
    public void addItem(OptionItem item){
        subActionItems.add(item);
    }

    public void centre(Point point){
        center=point;
        area = new RectF(center.x - radius, center.y - radius, center.x + radius, center.y + radius);
    }

    public void invalidateItem(){
        invalidateItem(center,radius,angle,startAngle);
    }

    public void  radius(int radius){
        this.radius=radius;
        area = new RectF(center.x - radius, center.y - radius, center.x + radius, center.y + radius);
    }

    private void init(){
        radius=300;
        angle = 360/VIEW_COUNT;
        center = new Point(0,0);
        area = new RectF(center.x - radius, center.y - radius, center.x + radius, center.y + radius);
        for(int i=0;i<VIEW_COUNT;i++){
            View view = inflate.inflate(R.layout.item_menu,null);
            this.addView(view);
            ViewHolder viewHolder = new ViewHolder();
            viewHolder.iv_icon = view.findViewById(R.id.iv_icon);
            viewHolder.tv_zh = view.findViewById(R.id.tv_zh);
            viewHolder.tv_en = view.findViewById(R.id.tv_en);
            view.setTag(viewHolder);
            viewHolder.tv_zh.setText(""+i);
            view.setOnClickListener(onClickListener);
            view.setOnTouchListener(onTouchListener);
            mViews.add(view);
        }
        setCurrPosition(0);
    }

    private ViewHolder getViewHolder(int position){
       return (ViewHolder) mViews.get(position).getTag();
    }

    private void invalidateItem(Point center, int radius, int angle, int startAngle) {
        Path orbit = new Path();
        orbit.addArc(area, startAngle, 360-angle);
        PathMeasure measure = new PathMeasure(orbit, false);

        int position;
        //顺序不可打乱
        position=startAngle/angle;
        setCurrPosition(-position);

        int divisor = VIEW_COUNT-1;
        ViewHolder viewHolder;
        for(int i=0; i<VIEW_COUNT; i++) {
            float[] coords = new float[] {0f, 0f};
            measure.getPosTan((i) * measure.getLength() / divisor, coords, null);
            View view = mViews.get(i);
            viewHolder=(ViewHolder)view.getTag();
            if(coords[0]<center.x){
                view.setVisibility(View.GONE);
            }else {
                view.setVisibility(View.VISIBLE);
                float alpha;
                float scale;
                if(startAngle==0){
                    if(i==0){
                        rightMost=Integer.valueOf((int) coords[0]);
                    }
                    if(i==1){
                        rightSecond=Integer.valueOf((int) coords[0]);
                    }
                }
                if(rightMost!=null&&rightSecond!=null) {
                    float max = rightMost - rightSecond;
                    float pro = coords[0] - rightSecond;
                    if (pro > 0) {
                        float s = pro / max;
                        alpha = s * (1 - ALPHA_MIN) + ALPHA_MIN;
                        scale = s * (1 - SCALE_MIN) + SCALE_MIN;
                    } else {
                        alpha = ALPHA_MIN;
                        scale = SCALE_MIN;
                    }
                }else{
                    if(i==0){
                        alpha = 1;
                        scale = 1;
                    }else {
                        alpha = ALPHA_MIN;
                        scale = SCALE_MIN;
                    }
                }
                view.bringToFront();
                view.setAlpha(alpha);
                viewHolder.iv_icon.setScaleX(scale);
                viewHolder.iv_icon.setScaleY(scale);
                int x = (int) coords[0] - MyUtil.DipToPixels(getContext(), ICON_SIZE/2);
                int y = (int) coords[1] - MyUtil.DipToPixels(getContext(), ICON_SIZE/2);
                view.setTranslationX(x);
                view.setTranslationY(y);
            }
        }

        ViewHolder[] viewHolders=getShowHolders();
        for (int i = 0; i < MAX_ITEM; i++) {
            OptionItem item = subActionItems.get(getOffsetCurrCheckItem(i));
            install(viewHolders[i],item);
           // LogUtil.e("install","itemPosition:"+getOffsetCurrCheckItem(i)+" viewHolder:"+i);
        }
        install(viewHolders[5],subActionItems.get(getOffsetCurrCheckItem(2)));
        install(viewHolders[6],subActionItems.get(getOffsetCurrCheckItem(3)));

    }

    private void install(ViewHolder viewHolder,OptionItem item){
        viewHolder.iv_icon.setImageResource(item.getImgId());
        viewHolder.tv_zh.setText(item.getZh());
        viewHolder.tv_en.setText(item.getEn());
        viewHolder.item=item;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
       userTouch(event);
        super.onTouchEvent(event);
        return true;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if(isMove)return true;
        return super.onInterceptTouchEvent(ev);
    }

    private void userTouch(MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                startMove= event.getRawY();
                break;
            case MotionEvent.ACTION_MOVE:
                    float move = event.getRawY();
                    float dis = startMove-move;
                    setStartAngle((int) (startAngle-(dis>0?dis/3+1:dis/3-1)));
                    startMove=move;
                    isMove =true;
                break;
        }

        if(event.getAction()==MotionEvent.ACTION_UP){
            isMove =false;
            scrollTo();
        }
    }

    public void scrollTo(){
        int rem=startAngle%angle;
        int end=startAngle;
        if(Math.abs(rem)>angle/2){
            end+=(rem>0?angle:-angle)-rem;
        }else{
            end-=rem;
        }
        ObjectAnimator animator = ObjectAnimator.ofInt(this,"startAngle" , startAngle, end);
        animator.setDuration(300);
        animator.start();
    }

    public void positionScrollTo(int position){
        int cha=getCurrPosition()-position;
        if(cha<-2)cha=cha+VIEW_COUNT;
        else if(cha>3)cha=cha-VIEW_COUNT;
        LogUtil.e("positionScrollTo","cha"+cha+",getCurrPosition()"+getCurrPosition()+",postion"+position);
        int end;
        end = startAngle+cha*angle;

        ObjectAnimator animator = ObjectAnimator.ofInt(this,"startAngle" , startAngle, end);
        animator.setDuration(300);
        animator.start();
    }

    public void setOnMenuItemClickListener(OnMenuItemClickListener onMenuItemClickListener) {
        this.onMenuItemClickListener = onMenuItemClickListener;
    }

    public interface OnMenuItemClickListener{
        void onMenuItemClick(OptionItem item);
    }

    static class ViewHolder{
        ImageView iv_icon;
        TextView tv_zh;
        TextView tv_en;
        OptionItem item;
    }

}
